﻿//======================================================================
// string类型的功能扩展类
//====================================================================== 

using System;
using System.Collections.Generic;

using System.Text;
using System.Text.RegularExpressions;

namespace Common
{
    /// <summary>
    /// string类型的功能扩展类
    /// </summary>
    public sealed class StringPlus
    {
        private static Regex RegNumber = new Regex( "^[0-9]+$" );

        #region 去除字符串最后一个','号

        /// <summary>
        /// 去除字符串最后一个','号
        /// </summary>
        /// <param name="chr">:要做处理的字符串</param>
        /// <returns>返回已处理的字符串</returns>
        public static string CutComma( string Input )
        {
            return CutComma( Input, "," );
        }

        /// <summary>
        /// 去除字符串最后一个','号
        /// </summary>
        /// <param name="Input"></param>
        /// <param name="indexStr"></param>
        /// <returns></returns>
        public static string CutComma( string Input, string indexStr )
        {
            if ( Input.IndexOf( indexStr ) >= 0 )
                return Input.Remove( Input.LastIndexOf( indexStr ) );
            else
                return Input;
        }

        #endregion

        #region 获取前N个字符串，如果超过则在后面补...

        /// <summary>
        /// 获取前N个字符串，如果超过则在后面补...
        /// </summary>
        /// <param name="stringToSub"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string StringDot( string stringToSub, int length )
        {
            Regex regex = new Regex( "[\u4e00-\u9fa5]+", RegexOptions.Compiled );

            char[] stringChar = stringToSub.ToCharArray();
            StringBuilder sb = new StringBuilder();
            int nLength = 0;
            bool isCut = false;
            for ( int i = 0; i < stringChar.Length; i++ )
            {
                if ( regex.IsMatch( ( stringChar[i] ).ToString() ) )
                {
                    sb.Append( stringChar[i] );
                    nLength += 2;
                }
                else
                {
                    sb.Append( stringChar[i] );
                    nLength = nLength + 1;
                }

                if ( nLength > length )
                {
                    isCut = true;
                    break;
                }
            }
            if ( isCut )
                return sb.ToString() + "...";
            else
                return sb.ToString();
        }

        #endregion

        #region 截取字符串，超过部分用指定字符串替换

        /* 宗波于 2010-6-12 日添加， 来源于DiscuzNt */
        /// <summary>
        /// 取指定长度的字符串
        /// </summary>
        /// <param name="p_SrcString">要检查的字符串</param>
        /// <param name="p_StartIndex">起始位置</param>
        /// <param name="p_Length">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static string GetSubString( string p_SrcString, int p_StartIndex, int p_Length, string p_TailString )
        {
            string myResult = p_SrcString;

            Byte[] bComments = Encoding.UTF8.GetBytes( p_SrcString );
            foreach ( char c in Encoding.UTF8.GetChars( bComments ) )
            {    //当是日文或韩文时(注:中文的范围:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韩文为\xAC00-\xD7A3)
                if ( ( c > '\u0800' && c < '\u4e00' ) || ( c > '\xAC00' && c < '\xD7A3' ) )
                {
                    //if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+"))
                    //当截取的起始位置超出字段串长度时
                    if ( p_StartIndex >= p_SrcString.Length )
                        return "";
                    else
                        return p_SrcString.Substring( p_StartIndex,
                                                       ( ( p_Length + p_StartIndex ) > p_SrcString.Length ) ? ( p_SrcString.Length - p_StartIndex ) : p_Length );
                }
            }

            if ( p_Length >= 0 )
            {
                byte[] bsSrcString = Encoding.Default.GetBytes( p_SrcString );

                //当字符串长度大于起始位置
                if ( bsSrcString.Length > p_StartIndex )
                {
                    int p_EndIndex = bsSrcString.Length;

                    //当要截取的长度在字符串的有效长度范围内
                    if ( bsSrcString.Length > ( p_StartIndex + p_Length ) )
                    {
                        p_EndIndex = p_Length + p_StartIndex;
                    }
                    else
                    {   //当不在有效范围内时,只取到字符串的结尾

                        p_Length = bsSrcString.Length - p_StartIndex;
                        p_TailString = "";
                    }

                    int nRealLength = p_Length;
                    int[] anResultFlag = new int[p_Length];
                    byte[] bsResult = null;

                    int nFlag = 0;
                    for ( int i = p_StartIndex; i < p_EndIndex; i++ )
                    {
                        if ( bsSrcString[i] > 127 )
                        {
                            nFlag++;
                            if ( nFlag == 3 )
                                nFlag = 1;
                        }
                        else
                            nFlag = 0;

                        anResultFlag[i] = nFlag;
                    }

                    if ( ( bsSrcString[p_EndIndex - 1] > 127 ) && ( anResultFlag[p_Length - 1] == 1 ) )
                        nRealLength = p_Length + 1;

                    bsResult = new byte[nRealLength];

                    Array.Copy( bsSrcString, p_StartIndex, bsResult, 0, nRealLength );

                    myResult = Encoding.Default.GetString( bsResult );
                    myResult = myResult + p_TailString;
                }
            }

            return myResult;
        }


        #endregion

        #region 过滤字符串中的html代码

        /// <summary>
        /// 过滤字符串中的html代码
        /// </summary>
        /// <param name="Str"></param>
        /// <returns>返回过滤之后的字符串</returns>
        public static string LostHTML( string Str )
        {
            return HTML.ClearHTMLTag(Str);
        }

        #endregion

        #region 检测含中文字符串实际长度

        /// <summary>
        /// 检测含中文字符串实际长度
        /// </summary>
        /// <param name="str">待检测的字符串</param>
        /// <returns>返回正整数</returns>
        public static int NumChar( string Input )
        {
            ASCIIEncoding n = new ASCIIEncoding();
            byte[] b = n.GetBytes( Input );
            int l = 0;
            for ( int i = 0; i <= b.Length - 1; i++ )
            {
                if ( b[i] == 63 )//判断是否为汉字或全脚符号
                {
                    l++;
                }
                l++;
            }
            return l;
        }

        #endregion

        #region 过滤字符串中可能对数据库进行攻击的非法字符

        /// <summary>
        /// 过滤字符串中可能对数据库进行攻击的非法字符
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public static string Filter( string sInput )
        {
            if ( sInput == null || sInput == "" )
                return null;
            string sInput1 = sInput.ToLower();
            string output = sInput;
            string pattern = @"*|and|exec|insert|select|delete|update|count|master|truncate|declare|char(|mid(|chr(|'";
            if ( Regex.Match( sInput1, Regex.Escape( pattern ), RegexOptions.Compiled | RegexOptions.IgnoreCase ).Success )
            {
                throw new Exception( "字符串中含有非法字符!" );
            }
            else
            {
                output = output.Replace( "'", "''" );
            }
            return output;
        }

        #endregion

        #region 字符串必须以"/"符号结尾

        /// <summary>
        /// 字符串必须以"/"符号结尾
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string LastBacklash( string input )
        {
            if ( input == null )
                return input;
            if ( !input.EndsWith( "/" ) )
                return input + "/";
            else
                return input;
        }

        #endregion

        #region 判断是否是IP地址格式

        /// <summary>
        /// 判断是否是IP地址格式 0.0.0.0
        /// </summary>
        /// <param name="str1">待判断的IP地址</param>
        /// <returns>true or false</returns>
        public static bool IsIPAddress( string str1 )
        {
            if ( str1 == null || str1 == string.Empty || str1.Length < 7 || str1.Length > 15 ) return false;

            string regformat = @"^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$";

            Regex regex = new Regex( regformat, RegexOptions.IgnoreCase );
            return regex.IsMatch( str1 );
        }

        #endregion

        #region 截取字符串函数

        /// <summary>
        /// 截取字符串函数
        /// </summary>
        /// <param name="Str">所要截取的字符串</param>
        /// <param name="Num">截取字符串的长度</param>
        /// <returns></returns>
        public static string GetSubString( string Str, int Num )
        {
            if ( Str == null || Str == "" )
            {
                return "";
            }
            string outstr = string.Empty;
            int n = 0;
            foreach ( char ch in Str )
            {
                n += System.Text.Encoding.Default.GetByteCount( ch.ToString() );

                if ( n > Num )
                {
                    break;
                }
                else
                {
                    outstr += ch;
                }
            }

            return outstr;
        }
        /// <summary>
        /// 截取字符串函数,如果超过指定长度则将超出的部分用指定字符串代替
        /// </summary>
        /// <param name="Str">所要截取的字符串</param>
        /// <param name="Num">截取字符串的长度</param>
        /// <param name="Num">截取字符串后省略部分的字符串</param>
        /// <returns></returns>
        public static string GetSubString( string Str, int Num, string LastStr )
        {
            return GetSubString( Str, 0, Num, LastStr );
        }

        #endregion

        #region 类型判断和转换
        /// <summary>
        /// 是否数字字符串
        /// </summary>
        /// <param name="inputData">输入字符串</param>
        /// <returns></returns>
        public static bool IsNumber( string inputData )
        {
            Match m = RegNumber.Match( inputData );
            return m.Success;
        }
        /// <summary>
        /// 判断对象是否为Int32类型的数字
        /// </summary>
        /// <param name="Expression"></param>
        /// <returns></returns>
        public static bool IsNumeric( object Expression )
        {
            return TypeParse.IsNumeric( Expression );
        }
        /// <summary>
        /// 是否是Double
        /// </summary>
        /// <param name="Expression"></param>
        /// <returns></returns>
        public static bool IsDouble( object Expression )
        {
            return TypeParse.IsDouble( Expression );
        }

        /// <summary>
        /// string型转换为bool型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的bool类型结果</returns>
        public static bool StrToBool( object Expression, bool defValue )
        {
            return TypeParse.StrToBool( Expression, defValue );
        }

        /// <summary>
        /// 将对象转换为Int32类型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static int StrToInt( object Expression, int defValue )
        {
            return TypeParse.StrToInt( Expression, defValue );
        }
        /// <summary>
        /// 将对象转换为Int64类型
        /// </summary>
        /// <param name="Expression">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int64类型结果</returns>
        public static long StrToInt64( object Expression, int defValue )
        {
            return TypeParse.StrToInt64( Expression, defValue );
        }
        /// <summary>
        /// int型转换为string型
        /// </summary>
        /// <returns>转换后的string类型结果</returns>
        public static string IntToStr( int intValue )
        {
            //
            return Convert.ToString( intValue );
        }
        /// <summary>
        /// string型转换为float型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的i结果</returns>
        public static float StrToFloat( object strValue, float defValue )
        {
            return TypeParse.StrToFloat( strValue, defValue );
        }
        /// <summary>
        ///  string型转换为decimal型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns></returns>
        public static decimal StrToDecimal( string strValue, decimal defValue )
        {
            return TypeParse.StrToDecimal( strValue, defValue );
        }
        /// <summary>
        /// 判断给定的字符串数组(strNumber)中的数据是不是都为数值型
        /// </summary>
        /// <param name="strNumber">要确认的字符串数组</param>
        /// <returns>是则返加true 不是则返回 false</returns>
        public static bool IsNumericArray( string[] strNumber )
        {
            return TypeParse.IsNumericArray( strNumber );
        }
        #endregion

        #region 返回字符串真实长度, 1个汉字长度为2

        /// <summary>
        /// 返回字符串真实长度, 1个汉字长度为2
        /// </summary>
        /// <returns></returns>
        public static int GetLength( string str )
        {
            return Encoding.Default.GetBytes( str ).Length;
        }

        #endregion

        #region Null Validate
        /// <summary>
        /// 判断是否是DBnull，是返回true,不是返回false
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsDBnull( object value )
        {
            if ( DBNull.Value == value )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// DBNull转为空
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string strDBNnullToString( object value )
        {
            string str = string.Empty;
            if ( DBNull.Value == value || value == null )
            {
                return str;
            }
            else
            {
                str = value.ToString();
            }
            return str;
        }

        public static string MakeEmptyStringNull( string source )
        {
            if ( source == null || source.Length == 0 || System.Text.RegularExpressions.Regex.Replace( source, @"\s*", "" ).Length == 0 )
                return null;

            return System.Text.RegularExpressions.Regex.Replace( source, @"\s*", "" );
        }

        /// <summary>
        /// 验证传入的参数都不是null
        /// </summary>
        /// <param name="args">参数列表</param>
        /// <returns></returns>
        public static bool Require( params string[] args )
        {
            bool allNotNull = true;

            foreach ( string item in args )
            {
                if ( MakeEmptyStringNull( item ) == null )
                {
                    allNotNull = false;
                    break;
                }
            }

            return allNotNull;
        } 
        #endregion

        #region String2Array
        /// <summary>
        /// 根据指定的char将字符串拆分成字符串数组
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="separator">分隔符</param>
        /// <returns></returns>
        public static string[] String2Array( string source, params char[] separator )
        {
            return source.Trim( separator ).Split( separator );
        }
        /// <summary>
        /// 用‘,’将字符串拆分成字符串数组
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <returns></returns>
        public static string[] String2Array( string source )
        {
            return String2Array( source, ',' );
        } 
        #endregion

        #region 截取指定长度的字符串

        /// <summary>
        /// 截取指定长度字符串
        /// </summary>
        /// <param name="start">截取起始位置</param>
        /// <param name="length">截取长度</param>
        /// <param name="str">要截取的字符串</param>
        /// <returns>string要等到的字符串，如不符合截取条件，则返回空字符串</returns>
        public static string GetNeedString(int start, int length, string str)
        {
            string strResult = string.Empty;
            
            if (string.IsNullOrEmpty(str))
            {
                return strResult;
            }

            if (str.Length < (start + length))
            {
                return str;
            }

            strResult = str.Substring(start, length);

            return strResult;
        }

        #endregion

        #region Merge String By No Repeat
        /// <summary>
        /// 无重复合并字符串,用于特殊用途.
        /// 例如:此功能用于将字符串 1,2,3,4,a,b,c 与 a,b,c,d,m,n 组合成 1,2,3,4,a,b,c,d,m,n
        /// </summary>
        /// <param name="orgStr">原始字符串</param>
        /// <param name="newStr">待合并字符串</param>
        /// <param name="orgSeparator">原始串中的分隔符</param>
        /// <param name="newSeparator">待合并串中的分隔符</param>
        /// <param name="joinSeparator">合并时用的分隔符</param>
        /// <returns></returns>
        public static string MergeNoRepeat( string orgStr, string newStr, string orgSeparator, string newSeparator, string joinSeparator )
        {
            List<string> orgList = new List<string>( String2Array( orgStr, orgSeparator.ToCharArray() ) );
            string[] newlist = String2Array( newStr, newSeparator.ToCharArray() );
            foreach ( string item in newlist )
            {
                if ( orgList.Contains( item ) )
                    continue;

                orgList.Add( item );
            }

            return string.Join( joinSeparator, orgList.ToArray() );
        }

        public static string MergeNoRepeat( string orgStr, string newStr, string separator, string joinSeparator )
        {
            return MergeNoRepeat( orgStr, newStr, separator, separator, joinSeparator );
        }

        public static string MergeNoRepeat( string orgStr, string newStr, string joinSeparator )
        {
            return MergeNoRepeat( orgStr, newStr, ",", ",", joinSeparator );
        }

        public static string MergeNoRepeat( string orgStr, string newStr )
        {
            return MergeNoRepeat( orgStr, newStr, ",", ",", "," );
        }
        #endregion

        #region 替换字符串中所有空格和换行
        /// <summary>
        /// 替换字符串中所有空格和换行
        /// </summary>
        /// <param name="str">需要替换的字符串</param>
        /// <returns></returns>
        public static string ReplaceSpaceAndEnter(string str)
        {
            string strReplace = string.Empty;
            str = Regex.Replace(str, @"[\n\r]", "");
            Regex re = new Regex(@"[\s]{2,}", RegexOptions.Compiled);
            strReplace = re.Replace(str.TrimEnd(), "");

            return strReplace;
        } 
        #endregion
    }
}
